using LiteDB;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace TestLiteDB
{
    class TestItem
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public int Value { get; set; }
        public string Description { get; set; }

        public TestItem()
        {
            Id = Guid.NewGuid().ToString("N");
        }
    }

    class Program
    {
        static string connStr = "filename=lt.db;Journal=false;";

        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo("log4net.config"));

            using (var conn = new LiteDB.LiteDatabase("lt.db"))
            {
                var col = conn.GetCollection<TestItem>();
                col.EnsureIndex(item => item.Name);
                col.EnsureIndex(item => item.Value);
            }

            for (int i = 0; i < 20; i++)
            {
                var thread = new Thread(AddThread);
                thread.IsBackground = true;
                thread.Start();
            }

            for (int i = 0; i < 5; i++)
            {
                var thread = new Thread(QueryThread);
                thread.IsBackground = true;
                thread.Start();
            }

            for (int i = 0; i < 10; i++)
            {
                var thread = new Thread(DeleteThread);
                thread.IsBackground = true;
                thread.Start();
            }

            //CopyTo();

            Console.ReadLine();
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            System.IO.File.AppendAllText("error.log", string.Format("[0] {1}\r\n", e.ExceptionObject));
        }

        private static void CopyTo()
        {
            var logger = log4net.LogManager.GetLogger("备份");

            try
            {
                using (var conn2 = new LiteDatabase("lt2.db"))
                using (var conn = new LiteDB.LiteDatabase(connStr))
                {
                    var cols = conn.GetCollectionNames();
                    foreach (var col in cols)
                    {
                        conn2.GetCollection(col).InsertBulk(conn.GetCollection(col).FindAll());
                    }
                }
            }
            catch (Exception ex)
            {
                logger.DebugFormat("复制异常{0}", ex);
            }

            //try
            //{
            //    using (var conn = new LiteDatabase("lt2.db"))
            //    {
            //        var cols = conn.GetCollectionNames();
            //        foreach (var col in cols)
            //        {
            //            var items = conn.GetCollection(col).FindAll();
            //            foreach (var item in items)
            //            {
            //                Console.WriteLine("名称：{0} 数值：{1} 说明：{2}", item["Name"], item["Value"], item["Description"]);
            //            }
            //        }
            //    }
            //}
            //catch (Exception ex)
            //{
            //    logger.DebugFormat("查询异常{0}", ex);
            //}

            try
            {
                using (var conn = new LiteDatabase("lt2.db"))
                {
                    var col = conn.GetCollection<TestItem>();
                    var items = col.FindAll();
                    foreach (var item in items)
                    {
                        Console.WriteLine("名称：{0} 数值：{1} 说明：{2}", item.Name, item.Value, item.Description);
                    }
                }
            }
            catch (Exception ex)
            {
                logger.DebugFormat("查询异常{0}", ex);
            }
        }

        private static void AddThread()
        {
            var rand = new Random(DateTime.Now.Millisecond);
            var logger = log4net.LogManager.GetLogger("添加");

            logger.Info("添加线程启动");

            while (true)
            {
                try
                {
                    using (var conn = new LiteDB.LiteDatabase(connStr))
                    {
                        var col = conn.GetCollection<TestItem>();
                        col.Insert(new TestItem
                        {
                            Name = "fdsfdsf",
                            Description = "dsfsdf",
                            Value = rand.Next()
                        });
                    }
                }
                catch (Exception ex)
                {
                    logger.DebugFormat("添加异常{0}", ex);
                }

                Thread.Sleep(1000);
            }
        }

        private static void QueryThread()
        {
            var rand = new Random(DateTime.Now.Millisecond);
            var logger = log4net.LogManager.GetLogger("查询");

            logger.Info("查询线程启动");

            while (true)
            {
                var lst = new List<TestItem>();

                try
                {
                    using (var conn = new LiteDB.LiteDatabase(connStr))
                    {
                        var col = conn.GetCollection<TestItem>();
                        var items = col.Find(Query.GT("Value", rand.Next()));
                        lst.AddRange(items);
                    }
                }
                catch (Exception ex)
                {
                    logger.DebugFormat("查询异常{0}", ex);
                }

                foreach (var item in lst)
                {
                    Console.WriteLine("名称：{0} 数值：{1} 说明：{2}", item.Name, item.Value, item.Description);
                }

                Thread.Sleep(1000);
            }
        }

        private static void DeleteThread()
        {
            var rand = new Random(DateTime.Now.Millisecond);
            var logger = log4net.LogManager.GetLogger("删除");

            logger.Info("删除线程启动");

            while (true)
            {
                try
                {
                    using (var conn = new LiteDB.LiteDatabase(connStr))
                    {
                        var col = conn.GetCollection<TestItem>();
                        col.Delete(Query.Between("Value", rand.Next(), rand.Next()));
                    }
                }
                catch (Exception ex)
                {
                    logger.DebugFormat("删除异常{0}", ex);
                }

                Thread.Sleep(1000);
            }
        }
    }
}